package com.apache.rpc.service;

import com.apache.api.vo.ParamsVo;
import com.apache.cache.service.impl.LoadCacheFactory;
import com.apache.cache.util.Validator;
import com.apache.database.exception.DaoAccessException;
import com.apache.rpc.common.RpcUtil;
import com.apache.rpc.entity.InterfaceRegister;
import com.apache.rpc.entity.RpcDatasource;
import com.apache.rpc.entity.SystemConfig;
import com.apache.rpc.manager.DynamicDatabaseManager;
import com.apache.rpc.manager.InterfaceRegisterManager;
import com.apache.rpc.manager.RpcDatasourceManager;
import com.apache.rpc.manager.SystemConfigManager;
import com.apache.rpc.service.impl.helper.CacheTactics;
import com.apache.task.api.ScheduledExecutor;
import com.apache.tools.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:定时任务
 *
 * @author dyh 创建时间：2018年03月13日
 */
@Component
@EnableScheduling
public class RpcScheduledPool {

    protected Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private InterfaceRegisterManager interfaceRegisterManager;

    @Autowired
    private RpcDatasourceManager rpcDatasourceManager;

    @Autowired
    private SystemConfigManager systemConfigManager;

    @Autowired
    private DynamicDatabaseManager taskTimerManager;

    private static transient boolean RpcScheduledPoolMark = true;

    private static transient boolean RpcInitConfigMark = true;

    private static transient boolean INIT_MARK = true;

    //每分钟执行一次
    @Scheduled(fixedRate = 20000)
    public void countFormulaTab() {
        if (RpcScheduledPoolMark) {
            RpcScheduledPoolMark = false;
            try {
                initConfig();
                if (INIT_MARK) {
                    INIT_MARK = false;
                    try {
                        Thread.sleep(2 * 60000l);//当首次启动RPC服务端后，延迟2分钟开始启用定时器
                    } catch (InterruptedException e) {
                    }
                }
                if (!CacheTactics.isIsOpenTask()) {
                    RpcScheduledPoolMark = true;
                    return;
                }
                Map<String, String> param = new HashMap<>();
                ParamsVo vo = new ParamsVo();
                InterfaceRegister register = new InterfaceRegister();
                register.setCallType("socket");
                vo.setObj(register);
                List<InterfaceRegister> list = interfaceRegisterManager.getList(vo);
                if (Validator.isEmpty(list))
                    return;
                for (int i = 0; i < list.size(); i++) {
                    InterfaceRegister ir = list.get(i);
                    if (StrUtil.isNotNull(param.get(ir.getAddress() + ":" + ir.getPort()))) {
                        if ("0".equals(param.get(ir.getAddress() + ":" + ir.getPort()))) {
                            ir.setFlag("0");
                            vo.setObj(ir);
                            interfaceRegisterManager.editInfo(vo);
                        }
                        continue;
                    }
                    param.put(param.get(ir.getAddress() + ":" + ir.getPort()), "1");
                    boolean socketConnect = RpcUtil.getInstance()
                            .isHostConnectable(ir.getAddress(), ir.getPort());
                    if (!socketConnect) {
                        log.debug("RPC Socket 通讯检测 [" + ir.getBeanId() + "]-[" + ir.getAddress()
                                + "]-[" + ir.getPort() + "]-[" + socketConnect + "]");
                        ir.setFlag("0");
                        vo.setObj(ir);
                        interfaceRegisterManager.editInfo(vo);
                        param.put(param.get(ir.getAddress() + ":" + ir.getPort()), "0");
                    } else if ("0".equals(ir.getFlag())) {
                        ir.setFlag("1");
                        vo.setObj(ir);
                        interfaceRegisterManager.editInfo(vo);
                    }
                }
            } finally {
                RpcScheduledPoolMark = true;
            }
        }
    }

    private void initConfig() {
        if (!RpcInitConfigMark) {//系统启动初始化缓存
            return;
        }
        try {
            RpcInitConfigMark = false;
            String isOpenCache = StrUtil.doNull(String.valueOf(
                    LoadCacheFactory.getInstance().getCacheManager("")
                            .getCacheObjectByKey("is.open.cache")), "F");
            ParamsVo vo = new ParamsVo();
            vo.setMethodKey("initCache");
            if ("F".equals(isOpenCache)) {
                SystemConfig config = new SystemConfig();
                vo.setObj(config);
                systemConfigManager.execute(vo);
            }
            RpcDatasource config = new RpcDatasource();
            vo.setObj(config);
            rpcDatasourceManager.execute(vo);
            try {
                vo.setKey("initCache");
                String isFile = StrUtil.doNull(RpcUtil.getInstance().getValueByKey("read.file.database"),"file");
                ScheduledExecutor.newInstance().setStratWay(isFile);
                if(!"file".equalsIgnoreCase(isFile)){
                    taskTimerManager.execute(vo);
                }
            }catch (DaoAccessException e){
            }
        } catch (Exception e) {
            RpcInitConfigMark = true;
        }
    }
}
